package com.dayu.finecomm.protocol.hd72;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dayu.finecomm.protocol.codec.Protocol;
import com.dayu.finecomm.protocol.codec.ProtocolDecoder;
import com.dayu.finecomm.protocol.pojo.TPacket;
import com.dayu.finecomm.protocol.pojo.TPacket.VType;
import com.dayu.finecomm.protocol.pojo.TSensor;

import io.netty.buffer.ByteBuf;

/**
 * STA协议解析，详见父类
 * 
 * @author Chenjiawei
 *
 *         2017年6月7日
 */
@Protocol(STADecoder.PROTO)
public class STADecoder extends ProtocolDecoder<TPacket> {

	static Logger LOGGER = LoggerFactory.getLogger(STADecoder.class);

	static final String PROTO = "HD72";
	static final String VPROTO = "HD76";

	static int STA_MAGIC_START = 0x5354413A; // STA:
	static int STA_MAGIC_END = 0x23; // #

	static String STR_KV = "([^:]+):([^;]+);"; // TM:1402282015;
	static Pattern KV = Pattern.compile(STR_KV);

	@Override
	public TPacket unpack(ByteBuf in) {

		String packet = in.toString(com.dayu.finecomm.utils.Helpers.ASCII);

		// STA:033;TM:1402282015;D:2;V:6.63;T:16;J7:1;C:85;L1:00000879;L2:00000000;P1:00543278|00543289|00543298|00543308|00543317|00543326|00543336|00543346|00543356|00543365|00543373|00543381|00543389|00543396|00543403|00543409;P2:00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000;12#

		Matcher m = KV.matcher(packet);

		TPacket pack = new TPacket(VType.RRR, VPROTO, -1, null);

		int nInterval = 0;
		int nCount = 1;

		while (m.find()) {

			String g1 = m.group(1);
			String g2 = m.group(2);

			switch (g1) {

			case "STA":
				pack.sn = g2;
				break;
			case "TM":
				pack.timestamp = com.dayu.finecomm.utils.Helpers.parseDate("yyMMddHHmm", g2);
				break;
			case "D":
				nInterval = HD76Convention.interval(NumberUtils.toShort(g2));
				break;
			case "T":
				nCount = NumberUtils.toInt(g2);
				break;
			default:

				// HACK: 2015-06-17 无时标的报文
				// STA:011;C:01;A1:0.349;J3:0;J5:0;32#
				if (pack.timestamp == null) {
					pack.timestamp = System.currentTimeMillis();
				}

				String channel = g1;
				String[] ss = g2.split("\\|");

				for (int i = 0; i < ss.length; i++) {

					Number num = null;

					if (ss[i].contains(".")) {
						num = NumberUtils.toDouble(ss[i]);
					} else {
						num = NumberUtils.toLong(ss[i]);
					}

					TSensor s = new TSensor(channel, num, pack.timestamp + nInterval * i);
					if ((g1.startsWith("K") || g1.startsWith("J"))) {
						s.val = num.doubleValue() != 0 ? 1 : 0;
					}

					if (ss.length == 1) {
						s.timestamp = pack.timestamp + nInterval * (nCount - 1);
					}

					pack.sensors.add(s);
				}

				break;
			}
		}

		return "-1".equals(pack.sn) ? null : pack;
	}

	@Override
	public int checkStart(ByteBuf in) {
		return 0;
	}

	@Override
	public int check(ByteBuf in) {

		if (in.readableBytes() < 8)
			return -1;

		long smagic = in.getUnsignedInt(0);

		if (smagic != STA_MAGIC_START)
			return -1;

		int n = in.readableBytes();

		for (int i = in.readerIndex(); i < n; i++) {

			final byte b = in.getByte(i);

			if (b == STA_MAGIC_END) {
				return i + 1;
			}
		}

		return -1;
	}

	@Override
	public Object timing() {
		return HD72Convention.timing();
	}

	@Override
	public byte[] echo() {

		return "@222".getBytes();
	}

}
